package com.turman.cnw

import android.provider.Settings
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import kotlinx.coroutines.*

import org.junit.Test
import org.junit.runner.RunWith

import org.junit.Assert.*
import kotlin.system.measureTimeMillis

/**
 * Instrumented test, which will execute on an Android device.
 *
 * See [testing documentation](http://d.android.com/tools/testing).
 */
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
    @Test
    fun useAppContext() {
        // Context of the app under test.
        val appContext = InstrumentationRegistry.getInstrumentation().targetContext
        assertEquals("com.turman.cnw", appContext.packageName)
    }

    @Test
    fun testLaunch() {
        val time:Long = measureTimeMillis {
            GlobalScope.launch {
                Thread.sleep(1000)
                println("testLaunch的launch中，${Thread.currentThread()} 我很好")
            }

            GlobalScope.launch {
                Thread.sleep(1000)
                println("testLaunch的launch2中，${Thread.currentThread()} 嘿嘿嘿")
            }
            println("你好么？${Thread.currentThread()}")
            Thread.sleep(2200)
        }
        println("函数总耗时 $time")
    }

    @Test
    fun testAsync() {
        val time:Long = measureTimeMillis {
            GlobalScope.async {
                Thread.sleep(1000)
                println("testLaunch的launch中，${Thread.currentThread()} 我很好")
            }

            GlobalScope.async {
                Thread.sleep(1000)
                println("testLaunch的launch2中，${Thread.currentThread()} 嘿嘿嘿")
            }
            println("你好么？${Thread.currentThread()}")
            Thread.sleep(2200)
        }
        println("函数总耗时 $time")
    }

    @Test
    fun testRunBlocking() {
        val time:Long = measureTimeMillis {
            runBlocking {
                println("before blocking ${Thread.currentThread()}")
                delay(500)
                println("after blocking ${Thread.currentThread()}")
            }
            println("something... ${Thread.currentThread()}")
        }
        println("总耗时 $time")
    }

    @Test
    fun testCancelJoin() {
        runBlocking {
            val time:Long = measureTimeMillis {
                val L1:Job = GlobalScope.launch {
                    println("Launch1 ${Thread.currentThread()} L1 Hello")
                }
                val L2:Job = GlobalScope.launch {
                    println("Launch2 ${Thread.currentThread()} L2 World")
                }

                val a2:Deferred<Unit> = GlobalScope.async {
                    repeat(20) {
                        println("a2 ${Thread.currentThread()} $it A2很好")
                        delay(20)
                    }
                }

                val a1:Deferred<Unit> = GlobalScope.async {
                    println("a1 ${Thread.currentThread()} A1你好")
                }
            }
            println("总耗时 $time")
        }
    }

    @Test
    fun testCancelJoin1() {
        runBlocking {
            val time:Long = measureTimeMillis {
                val L1:Job = launch {
                    println("Launch1 ${Thread.currentThread()} L1 Hello")
                }
                val L2:Job = launch {
                    println("Launch2 ${Thread.currentThread()} L2 World")
                }

                val a2:Deferred<Unit> = async {
                    repeat(20) {
                        println("a2 ${Thread.currentThread()} $it A2很好")
                        delay(20)
                    }
                }
//                a2.join()

                val a1:Deferred<Unit> = async {
                    println("a1 ${Thread.currentThread()} A1你好")
                    a2.cancel()
                }
            }
            println("总耗时 $time")
        }
    }

    @Test
    fun testCancelJoin2() {
        val time:Long = measureTimeMillis {
            val L1:Job = GlobalScope.launch {
                println("Launch1 ${Thread.currentThread()} L1 Hello")
            }
            val L2:Job = GlobalScope.launch {
                println("Launch2 ${Thread.currentThread()} L2 World")
            }

            val a2:Deferred<Unit> = GlobalScope.async {
                repeat(20) {
                    println("a2 ${Thread.currentThread()} $it A2很好")
                    delay(20)
                }
            }

            val a1:Deferred<Unit> = GlobalScope.async {
                println("a1 ${Thread.currentThread()} A1你好")
            }
        }
        println("总耗时 $time")
    }

    @Test
    fun testTimeout() {
        runBlocking {
            val time:Long = measureTimeMillis {
                withTimeout(3000) {
                    launch {
                        repeat(200) {
                            println("withTimeOut中 launch的${Thread.currentThread()} $it")
                            delay(300)
                        }
                    }
                }
                println("withTimeOut ${Thread.currentThread()}")

                withTimeoutOrNull(1000) {

                }
            }
        }
    }

    @Test
    fun testAwait() = runBlocking {
        val time:Long = measureTimeMillis {
            val a2:Deferred<Int> = async {
                println("this is a2 ${Thread.currentThread()}")
                delay(2000)
                99
            }

            val a1:Deferred<Int> = async {
                println("this is a1 ${Thread.currentThread()}")
                delay(3000)
                100
            }

            println("result ${Thread.currentThread()} -- ${a1.await()} ${a2.await()}")
        }
        println("耗时 $time")
    }

}